import { useEffect, useReducer } from 'react'

import TodoAdd from './components/context/TodoAdd'
import MainSection from './components/context/MainSection'
import TodoFooter from './components/context/TodoFooter'

import TodoContext from './TodoContext'

import { ToDoItem } from './ToDoItem'

import './App.css'

type ActionType =
  | { type: 'add'; payload: string }
  | { type: 'toggle'; payload: ToDoItem['id'] }
  | { type: 'delete'; payload: ToDoItem['id'] }
  | { type: 'loadData'; payload: ToDoItem[] }

const reducer = (state: ToDoItem[], action: ActionType) => {
  switch (action.type) {
    case 'add':
      return [
        ...state,
        {
          id: state.length === 0 ? 1 : state[state.length - 1].id + 1,
          text: action.payload,
          done: false
        }
      ]

    case 'toggle': {
      return state.map(todo => {
        if (todo.id === action.payload) {
          return {
            ...todo,
            done: !todo.done
          }
        }
        return todo
      })
    }

    case 'delete': {
      const newTodos = state.filter(item => item.id !== action.payload)
      return newTodos
    }

    case 'loadData': {
      return action.payload
    }

    default:
      return state
  }
}

function App () {
  const initialValue = [
    { id: 1, text: '吃饭2', done: true },
    { id: 2, text: '睡觉2', done: false }
  ]

  const [state, dispatch] = useReducer(reducer, initialValue)

  const onAddTodo = (text: string) => {
    dispatch({ type: 'add', payload: text })
  }

  // 更改选中状态
  const onCheckedChange = (id: number) => {
    dispatch({ type: 'toggle', payload: id })
  }

  // 删除
  const onDeleteTodo = (id: number) => {
    dispatch({ type: 'delete', payload: id })
  }

  /**
   * 功能：数据持久化到 localStorage 中
   *
   * 两件事：
   *  1. 组件加载时，读取 localStorage 中的数据，并渲染在组件中
   *  2. 任务数据改变时，将最新的数据，保存到 localStorage 中
   */

  // 启动时加载
  useEffect(() => {
    const res = localStorage.getItem('todos')
    if (res) {
      dispatch({ type: 'loadData', payload: JSON.parse(res) })
    }
  }, [])

  // todos改变之后，保存到本地
  useEffect(() => {
    localStorage.setItem('todos', JSON.stringify(state))
  }, [state])

  return (
    <section className='todoapp'>
      <TodoContext.Provider
        value={{
          todos: state,
          onAddTodo,
          onToggleTodo: onCheckedChange,
          onDeleteTodo
        }}
      >
        {/* 添加任务 */}
        <TodoAdd />
        {/* 中间内容 */}
        <MainSection></MainSection>
        {/* footer 组件 */}
        <TodoFooter />
      </TodoContext.Provider>
    </section>
  )
}

export default App
